<?php
/**
 * Created by PhpStorm.
 * User: aiChenK
 * Date: 2018-11-08
 * Time: 16:29
 */

namespace Services\Login;

use Helpers\Di;
use Helpers\Hrm;
use Helpers\Main;
use Helpers\Session;
use Helpers\Tool;
use Helpers\User;   //todo 替换
use Services\Sys\ValidCode;
use Services\Login\Models\Auth;

class Login
{

    /**
     * 获取登陆用户信息
     *
     * @return Auth
     *
     * create by ck 20190103
     */
    public static function getInfo()
    {
        static $auth;
        if (empty($auth)) {
            $auth = Session::get('auth', []);
        }
        return $auth;
    }

    /**
     * 判断是否登陆
     *
     * @return bool
     *
     * create by ck 20190103
     */
    public static function isLogin()
    {
        return Session::has('auth');
    }

    /**
     * 获取当前用户id
     *
     * @return int
     *
     * create by ck 20190103
     */
    public static function getId()
    {
        return intval(self::getInfo()->userId);
    }

    /**
     * 是否为超级管理员
     *
     * @return bool
     *
     * create by ck 20190103
     */
    public static function isAdmin()
    {
        $adminUser = ['admin'];
        return in_array(strtolower(self::getInfo()->logonName), $adminUser);
    }

    /**
     * 是否为员工
     *
     * @return array|bool|string
     *
     * create by ck 20190114
     */
    public static function isStaff()
    {
        return User::isStaff(self::getId());
    }

    /**
     * 根据账号获取用户登陆所需信息
     *
     * @param string $account
     * @return object
     * @throws \Exception
     *
     * create by ck 20190114
     */
    private static function getUserInfoByAccount(string $account)
    {
        static $user;
        if (!$user) {
            $sql = "SELECT u.iUserId,u.sLogonName,u.sUserName,u.iUserType,u.sLogonPwd,u.sSelfPhone,u.iSchoolId
                FROM XHSys_User AS u
                LEFT JOIN XHHrm_Staff AS s
                  ON u.iUserId = s.iUserId AND s.bDelete = 0
                WHERE u.bDelete = 0 AND u.bDisable = 0 AND (u.sLogonName = :account OR u.sSelfPhone = :account)
                ORDER BY s.iStaffId DESC,u.iUserId ASC";
            $user = Di::get()->db->fetchOne($sql, 2, ['account' => $account]);
            if (!$user) {
                throw new \Exception('用户不存在');
            }
            $user = (object)$user;
        }
        return $user;
    }

    /**
     * 登陆
     *
     * @param string $account
     * @param string $password
     * @throws \Exception
     *
     * create by ck 20190104
     * modify by ck 20190223    兼容老数据，待删除
     */
    public static function doLogin(string $account, string $password)
    {
        //获取用户
        $user = self::getUserInfoByAccount($account);

        //判断密码
        if (strtolower($user->sLogonPwd) != md5($password)) {
            throw new \Exception('密码错误');
        }

        //非员工且为学生/家长则拒绝登陆
        $isStaff = User::isStaff($user->iUserId);
        if (!$isStaff && in_array($user->iUserType, [1, 5])) {
            throw new \Exception('禁止登陆');
        }

        //写入session
        $auth            = new Auth();
        $auth->userId    = $user->iUserId;
        $auth->logonName = $user->sLogonName;
        $auth->userName  = $user->sUserName;
        $auth->phone     = $user->sSelfPhone;
        $auth->userType  = $user->iUserType;
        $auth->schoolId  = $user->iSchoolId;

        //todo 删除 start
        try {
            $depInfo = Hrm::getDepInfoByUser($auth->userId);
        } catch (\Exception $e) {
            $depInfo = [];
        }
        $auth->depId   = array_column($depInfo, 'id');
        $auth->depTag  = array_filter(array_column($depInfo, 'tag'));
        $auth->depName = array_column($depInfo, 'name');
        //删除 end

        if (!Session::set('auth', $auth)) {
            throw new \Exception('登陆失败');
        }
    }

    /**
     * 根据账号判断是否需要发送验证码
     *
     * @param string $account
     * @return bool
     *
     * create by ck 20190114
     */
    public static function needValidCode(string $account)
    {
        $sysConfig = Main::getConfigByName('admin');

        //判断是否需要发送验证码登陆
        if ($account == 'admin') {
            return !!Tool::getValue($sysConfig, 'phone');
        } else {
            //处理需发送部门
            $needSmsCodeDep = Tool::getValue($sysConfig, 'needSmsCodeDep', [], function ($value) {
                return array_filter(explode('|', $value));
            });
            $user = self::getUserInfoByAccount($account);
            if (!$user->sSelfPhone) {
                return false;
            }
            try {
                $depInfo = Hrm::getDepInfoByUser($user->iUserId);
            } catch (\Exception $e) {
                $depInfo = [];
            }
            $checkDep = array_intersect($needSmsCodeDep, array_column($depInfo, 'tag'))
                || $needSmsCodeDep[0] == 'all';
            return $checkDep;
        }
    }

    /**
     * 验证手机验证码
     *
     * @param $account
     * @param $code
     * @return bool
     * @throws \Exception
     *
     * create by ck 20190114
     */
    public static function checkValidCode($account, $code)
    {
        if ($account == 'admin') {
            $sysConfig = Main::getConfigByName('admin');
            $phone = Tool::getValue($sysConfig, 'phone');
        } else {
            $phone = self::getUserInfoByAccount($account)->sSelfPhone;
        }
        if (!$phone) {
            throw new \Exception('无手机号，无法验证');
        }
        return ValidCode::check($phone, $code, ValidCode::TYPE_LOGIN);
    }

    /**
     * 根据账号获取手机号
     *
     * @param $account
     * @return mixed|string
     *
     * create by ck 20190115
     */
    public static function getPhoneByAccount($account)
    {
        if ($account == 'admin') {
            $sysConfig = Main::getConfigByName('admin');
            return Tool::getValue($sysConfig, 'phone');
        } else {
            return self::getUserInfoByAccount($account)->sSelfPhone;
        }
    }
}
